mod generate;
mod parse;

use proc_macro::TokenStream;
use syn::{parse_macro_input, Ident, ReturnType, Type, Visibility};

use crate::generate::generate;

#[derive(Clone)]
pub(crate) enum RetType {
    Empty,
    Type(Box<Type>),
}

pub(crate) struct ServiceMacroOption {
    server_side: bool,
    client_side: bool,
    static_ref_deep_down: (bool, bool),
}

pub(crate) struct RpcServiceTrait {
    vis: Visibility,
    name: Ident,
    fns: Vec<RpcProcedure>,
}

pub(crate) struct TypedIdent(pub(crate) Ident, pub(crate) Box<Type>);

pub(crate) struct RpcProcedure {
    fn_name: Ident,
    args: Vec<TypedIdent>,
    ret_type: RetType,
}

#[proc_macro_attribute]
pub fn rpc_service(attri: TokenStream, item: TokenStream) -> TokenStream {
    let option = parse_macro_input!(attri as ServiceMacroOption);
    let service_trait = parse_macro_input!(item as RpcServiceTrait);
    generate(option, service_trait)
}
